# -*- coding: utf-8 -*-
#    Copyright 2005 Spike^ekipS <spikeekips@gmail.com>
#
#       This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import nokcene.query
import cElementTree as etree
from nokcene.xmlquery import XMLSearchQuery as XMLSearchQueryOld
import func


class XMLSearchQuery (XMLSearchQueryOld) :

	def __init__ (self, xml_stream="") :
		XMLSearchQueryOld.__init__(self, xml_stream)

	def parseFields (self) :
		# fields
		fields = self.doc.findall("fields/field")
		for field in fields :
			self._search_fields.append(self.parseField(field))

	def parseField (self, field) :
		__children = field.getchildren()
		if len(__children) > 0 :

			__fields = list()
			__condition = "OR"
			if field.attrib.get("condition") is not None :
				__condition = unicode(field.attrib["condition"]).strip()

			__fields.append(__condition)
			for i in __children :
				__fields.append(self.parseField(i))

			return tuple(__fields)
		else :
			"""
			if field.attrib.get("id") and field.attrib.get("value") :
				mapping = { \
					"id" : unicode(field.attrib["id"].strip()),
					"value" : unicode(field.attrib["value"].strip()),
					"type" : unicode(field.attrib.get("type", "").strip()),
					"analyzer" : unicode(field.attrib.get("analyzer", "standard")).strip(),
				}
			"""

			mapping = dict()
			if field.attrib.get("condition") is not None :
				mapping["condition"] = unicode(field.attrib["condition"]).strip()

			if field.attrib.get("id") is not None :
				mapping["id"] = unicode(field.attrib["id"]).strip()

			if field.attrib.get("value") is not None :
				mapping["value"] = unicode(field.attrib["value"]).strip()

			if field.attrib.get("type") is not None :
				mapping["type"] = unicode(field.attrib["type"]).strip()

			if field.attrib.get("analyzer") is not None :
				mapping["analyzer"] = unicode(field.attrib["analyzer"]).strip()

			if field.attrib.get("usage") is not None :
				mapping["usage"] = unicode(field.attrib["usage"]).strip()

			return mapping

	def getSearchFields(self) :
		# Add path field type at the end

		_fields = []
		_ends = []
		for each in self._search_fields :
			#if each["type"].lower() == "path" :
			#	_ends.append(each)
			#else :
			#	_fields.append(each)
			_fields.append(each)

		for each in _ends :
			_fields.append(each)

		return tuple(_fields)

def xml_to_args (xml) :
	xs = XMLSearchQuery(xml)
	return ( \
		xs.getReturnFields(), \
		xs.getSearchFields(), \
		xs.getSearchOptions(), \
	)

TEMPLATE_XMLQUERY_DOC = \
"""<?xml version="1.0" encoding="utf-8"?>
<search>%s
</search>
"""
TEMPLATE_XMLQUERY_FIELDS = \
"""
	<fields>%s
	</fields>"""
TEMPLATE_XMLQUERY_FIELD_CONDITION = \
"""
		<field condition="%(condition)s">%(subqueries)s
		</field>
"""
TEMPLATE_XMLQUERY_FIELD = \
"""
		<field id="%(id)s" value=%(value)s usage="%(usage)s" type="%(type)s"
			analyzer="cjk" />"""
TEMPLATE_XMLQUERY_RETURN_FIELDS = \
"""
	<return_fields>%s
	</return_fields>"""
TEMPLATE_XMLQUERY_RETURN_FIELD = \
"""
		<field>%s</field>"""

TEMPLATE_XMLQUERY_SEARCH_OPTIONS = \
"""
	<sort>
		<sort-on>%(sort-on)s</sort-on>
		<sort-order>%(sort-order)s</sort-order>
		<sort-limit>%(size)s</sort-limit>
		<operator>%(operator)s</operator>
	</sort>
	<batch start="%(start)s" size="%(size)s"/>"""

# create query xml for searchQuery(XMLRPC API)
def args_to_xml  \
		(return_fields=dict(), search_fields=dict(), search_options=dict()) :

	def __generate_return_fields (fields) :
		# RETURN FIELDS
		__list_return_fields = list()
		for i in fields :
			__list_return_fields.append(TEMPLATE_XMLQUERY_RETURN_FIELD % i)

		return TEMPLATE_XMLQUERY_RETURN_FIELDS % \
				("".join(__list_return_fields), )

	def __generate_field (field) :
		if type(field) in (tuple, list, ) : # it has subquery.
			__condition = field[0]
			__list_subquery = list()
			for i in field[1:] :
				__list_subquery.append(__generate_field(i))

			__subqueries = "".join(__list_subquery)
			__kwargs = { \
				"condition" : __condition, \
				"subqueries" : __subqueries, \
			}
			return TEMPLATE_XMLQUERY_FIELD_CONDITION % __kwargs
		else :
			try :
				field["value"] = func.quote_xml_attr(field["value"])
			except Exception, e :
				print e
				raise

			__field = { \
				"id" : "", \
				"value" : "", \
				"usage" : "", \
				"type" : "", \
				"condition" : "OR", \
			}
			__field.update(field)

			return TEMPLATE_XMLQUERY_FIELD % __field

	def __generate_fields (fields) :
		# FIELDS
		__list_fields = list()
		for i in fields :
			#__list_fields.append(__generate_field(i))
			__list_fields.append(__generate_field(i))

		return TEMPLATE_XMLQUERY_FIELDS % ("".join(__list_fields), )

	def __generate_options (options) :
		# SORT
		__search_options = { \
			"sort-on" : "", \
			"sort-order" : "", \
			"sort-limit" : "", \
			"operator" : "", \
			"start" : "", \
		}
		__search_options.update(options)
		return TEMPLATE_XMLQUERY_SEARCH_OPTIONS % __search_options

	__xml = \
		TEMPLATE_XMLQUERY_DOC % \
			( \
				__generate_return_fields(return_fields) + \
				__generate_fields(search_fields) + \
				__generate_options(search_options) \
			)

	return __xml

"""
Description
-----------


ChangeLog
---------


Usage
-----


"""

__author__ =  "Spike^ekipS <spikeekips@gmail.com>"
__version__=  "0.1"
__nonsense__ = ""

__file__ = "1.py"


